home *** CD-ROM | disk | FTP | other *** search
/ Language/OS - Multiplatform Resource Library / LANGUAGE OS.iso / oper_sys / emerald / emrldsys.lha / Language / Compiler / symbolTable.c < prev    next >
Encoding:
C/C++ Source or Header  |  1990-08-16  |  5.3 KB  |  212 lines

  1. /*
  2.  * @(#)symbolTable.c    1.2  3/18/87
  3.  */
  4. #include "assert.h"
  5. #include "symbols.h"
  6. #include "nodes.h"
  7. #include "system.h"
  8. #include "map.h"
  9. #include "semantics.h"
  10. #include "sequence.h"
  11. #include "scan.h"
  12.  
  13. char *ST_KindName[] = {
  14.   "ST_Unknown",
  15.   "ST_Const",
  16.   "ST_Var",
  17.   "ST_Param",
  18.   "ST_Result",
  19.   "ST_OpName"};
  20.  
  21. /*
  22.  * There is a default symbol table that is used when parsing and resolving
  23.  * the symbols in the newly parsed stuff.  It is a static version of
  24.  * a SymbolTable, but it is made out of blocks.
  25.  */
  26. SymbolNumber nextSymbolToAllocate = FIRSTSYMBOL;
  27. int nestingDepth = 0;
  28. static SymbolBlockPtr symbolBlocks[20];
  29.  
  30. static ScopePtr currentScope = NULL;
  31.  
  32. static Map scopeMap = NULL;
  33.  
  34. void ST_EnterNewScope(fNodePtr, c)
  35. NodePtr fNodePtr;
  36. ST_Contexts c;
  37. {
  38.   register ScopePtr p;
  39.   nestingDepth ++;
  40.   p = (ScopePtr) malloc(sizeof(Scope));
  41.   p->enclosing = currentScope;
  42.   p->itsContext = c;
  43.   p->first = NULL;
  44.   p->itsNode = fNodePtr;
  45.   p->nestingDepth = nestingDepth;
  46.   currentScope = p;
  47.   Map_Insert(scopeMap, (int)fNodePtr, (int)p);
  48. }
  49.  
  50. void ST_EnterOldScope(fNodePtr)
  51. NodePtr fNodePtr;
  52. {
  53.   ScopePtr p;
  54.   p = (ScopePtr) Map_Lookup(scopeMap, (int)fNodePtr);
  55.   nestingDepth ++;
  56.   assert(p->enclosing == currentScope);
  57.   assert(p->nestingDepth == nestingDepth);
  58.   currentScope = p;
  59. }
  60.  
  61. void ST_ExitScope()
  62. {
  63.   currentScope = currentScope->enclosing;
  64.   nestingDepth = currentScope == NULL ? 0 : currentScope->nestingDepth;
  65. }
  66.  
  67. Symbol ST_iDefine();
  68.  
  69. Symbol ST_Lookup(fIdent, depth)
  70. Ident fIdent;
  71. int depth;
  72. {
  73.   register ScopePtr c;
  74.   register Symbol e;
  75.   register NodePtr q;
  76.   NodePtr fixup = NULL;
  77.   Symbol answer = NULL;
  78.   
  79.   assert(depth == 1 || depth == 2);
  80.   for (c = currentScope; c != NULL; c = c->enclosing) {
  81.     for (e = c->first; e != NULL; e = e->v.next) {
  82.       if (e->itsIdent == fIdent) goto foundit;
  83.     }
  84.     if (depth == 1) return(NULL);
  85.     if (depth == 2 && (c->itsContext == C_ObLit || c->itsContext == C_ATLit)){
  86.       /*
  87.        * We have discovered a place where we import an identifier that we do
  88.        * not define.  We need to make sure that every object/AT literal
  89.        * between where the symbol is defined and where it is used also
  90.        * imports it.
  91.        */
  92.       nextLineNumber = c->itsNode->lineNumber;
  93.       q = Construct(P_SETQ, 3, Construct(P_SYMDEF, 0), NULL, Construct(P_SYMREF, 0));
  94.       q->b.setq.outer->b.symref.ident = fIdent;
  95.       q->b.setq.inner->b.symdef.ident = fIdent;
  96.       q->b.setq.inner->b.symdef.symbol = ST_iDefine(fIdent, ST_Param, c);
  97.       q->b.setq.inner->b.symdef.symbol->isImport = TRUE;
  98.       if (answer == NULL) answer = q->b.setq.inner->b.symdef.symbol;
  99.       assert(c->itsNode->tag == P_OBLIT || c->itsNode->tag == P_ATLIT);
  100.       Sequence_Add(&c->itsNode->b.oblit.setq, q);
  101.       if (fixup != NULL) fixup->b.symref.symbol = q->b.setq.inner->b.symdef.symbol;
  102.       fixup = q->b.setq.outer;
  103.     }
  104.   }
  105.   return(NULL);
  106. foundit:
  107.   if (fixup != NULL) fixup->b.symref.symbol = e;
  108.   return(answer == NULL ? e : answer);
  109. }
  110.  
  111. Symbol ST_iDefine(fIdent, kind, c)
  112. Ident fIdent;
  113. ST_Kinds kind;
  114. register ScopePtr c;
  115. {
  116.   register SymbolBlockPtr sbp;
  117.   register Symbol p;
  118.   register int realS, blockIndex;
  119.  
  120.   p = (Symbol) calloc(sizeof(STEntry), 1);
  121.   p->tag = P_SYMBOL;
  122.   p->itsIdent = fIdent;
  123.   p->itsName = Ident_Name(fIdent);
  124.   p->itsSymbolNumber = nextSymbolToAllocate++;
  125.   p->itsKind = kind;
  126.   realS = p->itsSymbolNumber - FIRSTSYMBOL;
  127.   blockIndex = realS / STENTRIESPERBLOCK;
  128.   sbp = symbolBlocks[blockIndex];
  129.   if (sbp == NULL) {
  130.     sbp = (SymbolBlockPtr) malloc(sizeof(SymbolBlock));
  131.     symbolBlocks[blockIndex] = sbp;
  132.   }
  133.   sbp->symbols[realS % STENTRIESPERBLOCK] = p;
  134.   p->nestingDepth = c->nestingDepth;
  135.   p->v.next = c->first;
  136.   c->first = p;
  137.   return(p);
  138. }
  139.  
  140. Symbol ST_Define(fIdent, kind, depth)
  141. Ident fIdent;
  142. ST_Kinds kind;
  143. int depth;
  144. {
  145.   register ScopePtr c;
  146.  
  147.   if (ST_Lookup(fIdent, depth) != 0) {
  148.     return (NULL);
  149.   }
  150.   c = currentScope;
  151.   return(ST_iDefine(fIdent, kind, c));
  152. }
  153.  
  154. int getNestingDepth(fNodePtr)
  155. NodePtr fNodePtr;
  156. {
  157.   ScopePtr p;
  158.   p = (ScopePtr) Map_Lookup(scopeMap, (int)fNodePtr);
  159.   assert((int) p != NIL);
  160.   return(p->nestingDepth);
  161. }
  162.  
  163. #define ISANOBJECT(C) ((C) == C_ObLit || (C) == C_ATLit)
  164. int Symbol_IsImport(sym)
  165. register Symbol sym;
  166. {
  167.   register ScopePtr t = currentScope;
  168.   while (t != NULL && ! ISANOBJECT(t->itsContext)) t = t->enclosing;
  169.   return (t == NULL ? FALSE : sym->nestingDepth < t->nestingDepth);
  170. }
  171.  
  172. Symbol ST_Create(fNodePtr, fIdent)
  173. NodePtr fNodePtr;
  174. Ident fIdent;
  175. {
  176.   register Symbol p;
  177.   register SymbolBlockPtr sbp;
  178.   int realS, blockIndex;
  179.   register ScopePtr sp = NULL;
  180.  
  181.   if (fNodePtr != NULL)
  182.     sp = (ScopePtr) Map_Lookup(scopeMap, (int) fNodePtr);
  183.   if ((int)sp == NIL) sp = NULL;
  184.   p = (Symbol) calloc(sizeof(STEntry), 1);
  185.   p->tag = P_SYMBOL;
  186.   p->itsIdent = fIdent;
  187.   p->itsName = Ident_Name(fIdent);
  188.   p->itsSymbolNumber = nextSymbolToAllocate++;
  189.   p->nestingDepth = sp == NULL ? 0 : sp->nestingDepth;
  190.   p->itsKind = ST_Unknown;
  191.   realS = p->itsSymbolNumber - FIRSTSYMBOL;
  192.   blockIndex = realS / STENTRIESPERBLOCK;
  193.   sbp = symbolBlocks[blockIndex];
  194.   if (sbp == NULL) {
  195.     sbp = (SymbolBlockPtr) malloc (sizeof(SymbolBlock));
  196.     symbolBlocks[blockIndex] = sbp;
  197.   }
  198.   sbp->symbols[realS % STENTRIESPERBLOCK] = p;
  199.   if (sp != NULL) {
  200.     p->v.next = sp->first;
  201.     sp->first = p;
  202.   }
  203.   return(p);
  204.  
  205.     
  206. }
  207.  
  208. void initializeSymbolTable()
  209. {
  210.   scopeMap = Map_Create();
  211. }
  212.